--RedzoneRP
--By Kylegar



AddCSLuaFile("cl_init.lua")
AddCSLuaFile("hud.lua")
AddCSLuaFile("shared.lua")
AddCSLuaFile("cl_vgui.lua")
AddCSLuaFile("VGUI/rz_textpanel/cl_init.lua")
AddCSLuaFile("cl_skilldescriptions.lua")
AddCSLuaFile("shd_itemfunctions.lua")




include("shared.lua")
include("sv_accounts.lua")
include("sv_consolecommands.lua")
include("shd_itemfunctions.lua")
include("healthpack.lua")

local zombiesoff = true


local lasttime = CurTime()
local Experiance = "experiance"
local Level = "level"
local Xpfornextlevel = "xpfornextlevel"

local NPCCount = 0

function GM:Initialize()
	--If theres anyone connected when the gamemode is loaded, Load or create thier accounts
	if(player.GetAll() != nil) then
		for k , v in pairs(player.GetAll()) do
			if(file.Exists("Redzone/"..v:UniqueID()..".txt")) then
				loadaccount(v)
			else
				createaccount(v)
			end
		end
	end	
	
end




	

function GM:PlayerInitialSpawn(ply)
	--Set Teams, make sure they have a weapon, and load thier account
	ply:SetTeam(101)
	
	if !(file.Exists("Redzone/"..ply:UniqueID()..".txt")) then
		createaccount(ply)
	else		
		loadaccount(ply)
	end	
	local camera = ents.Create("sent_rzcam")
	camera:Spawn()
	camera:SettargPlayer(ply)
	
	ply:SetViewEntity(camera)
	ply:SetHealth(ply:GetPlayerMaxHealth())
	ply:CreateInvitory()
end

--This is a backup function in the off event that a player's view entity isnt set on first spawn.  
function GM:PlayerSpawn(ply)
	
	ply:Give("weapon_crowbar")
	ply:SetHealth(ply:GetPlayerMaxHealth())
end

	
local savedelay = CurTime()	
	
function GM:Think()
	
	--Dont need them headcrabs
	for k ,v in pairs(ents.FindByClass("npc_headcra*")) do
		if(v:IsValid()) then
			v:Remove()
		end
	end
	
	

	--Save everyone's accounts just in case the server crashes.  Happens every 5 min	
	if (CurTime() > savedelay) then
		for k,i in pairs(player.GetAll()) do
			if(file.Exists("Redzone/"..i:UniqueID()..".txt")) then
				saveaccount(i)
			else
				createaccount(i)
			end
			
		end
	savedelay=CurTime()+300
	Msg("\nAll Players Accounts saved\n")
	end
	
	
	if(zombiesoff) then return end
	if (CurTime() > lasttime ) then
		
	--Test Spawn Code
		for k,v in pairs(player.GetAll()) do
		 if(NPCCount<100) then	
			if(math.random(1,2) == 1) then
			 npc = ents.Create("npc_zombie")
			else
			 npc = ents.Create("npc_fastzombie")
			end
			local spawnpos
			if(math.random(1,10)==5)then
			 spawnpos = v:GetPos() - (v:GetForward()*50) + Vector(math.random(-10,10),math.random(-10,10),20)
			else
			 spawnpos = v:GetPos() + (v:GetForward()*600) + Vector(math.random(-50,50),math.random(-50,50),20)
			end
			local trdata = {}
			trdata.start = v:GetPos()
			trdata.endpos = spwanpos
			trdata.filter = v
			local trace = util.TraceLine(trdata)
			if(trace.HitWorld) then
			 spawnpos = trace.HitNormal * 10
			end
			
			
			
			
			npc:SetPos(spawnpos)
			npc:DropToFloor()
			if(npc:IsInWorld()) then
				npc:Spawn()
				NPCCount = NPCCount+1
			else
				npc:Remove()
				Msg("NPC was outside the map, removing\n")
			end
			
		 else
			Msg("too many NPCS\n")
		 end	
			
		end
	lasttime = CurTime()+3
	end
	
end


--General Friendly Fire calls
function GM:PlayerShouldTakeDamage( victem , attacker)
	if(attacker == victem ) then return true end
	if(attacker:IsNPC()) then return true end
	if(attacker:IsPlayer()) then return false end
	
end

--For some reason, killing NPCs dont give you a frag...Fixed that...
function GM:OnNPCKilled( victem , killer , weapon)
	if(killer:IsPlayer()) then
		killer:SetFrags(killer:Frags()+1)	
		
		if(killer:GetXP() >= killer:GetXPForNextLevel()) then
			killer:LevelUp()			
			for k ,v in pairs(player.GetAll()) do
				v:PrintMessage(HUD_PRINTTALK, killer:GetName().." has leveled up to level "..killer:GetLevel())
			end
		end
			
	end
	
	NPCCount = NPCCount - 1
	
end

--XP Based on damage done
function GM:ScaleNPCDamage(npc , hitgroup , dmginfo)
	if(dmginfo:GetInflictor():IsPlayer()) then
		Msg(dmginfo:GetInflictor():GetName().."'s attack did "..dmginfo:GetDamage().." damage, giving "..dmginfo:GetDamage().." XP\n")		
		dmginfo:GetInflictor():AddXP( math.Round(dmginfo:GetDamage()))		
	end
end

--Save players accounts when they disconnect
function GM:PlayerDisconnected(ply)
	saveaccount(ply)
end

function GM:PlayerDeath(ply,weap,killer)
	
end

function cleanNPCs(p,c,a)
	if !(p:IsAdmin()) then return end
	for k,v in pairs(ents.FindByClass("npc_*")) do
	  v:Remove()
	  NPCCount=NPCCount - 1
	end

end
concommand.Add("rz_debug_cleanNPCs",cleanNPCs)

function zombiesofff(p,c,a)
	zombiesoff=true
end
concommand.Add("rz_debug_zombiesoff",zombiesofff)

function zombieson(p,c,a)
	zombiesoff=false
end
concommand.Add("rz_debug_zombieson",zombieson)